package quant.smart.crawl.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class HttpUtil {

	public static String post(String url, Map<String, String> params) 
			throws Exception {
		return post(url, params, null, null);
	}

	public static String post(String url, Map<String, String> params,Map<String, String> header, Map<String, String> outCookies) 
			throws Exception{
		String body = "";
		String encoding ="utf-8";
		String contentType="text/html";
		CookieStore cookieStore = new BasicCookieStore();
		HttpClientContext localContext = HttpClientContext.create();
		localContext.setCookieStore(cookieStore);
		CloseableHttpClient client = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		if(header!=null){
			if(header.get("Accept")!=null) httpPost.setHeader("Accept", header.get("Accept"));
			if(header.get("Cookie")!=null) httpPost.setHeader("Cookie", header.get("Cookie"));
			if(header.get("Accept-Encoding")!=null) httpPost.setHeader("Accept-Encoding", header.get("Accept-Encoding"));
			if(header.get("Accept-Language")!=null) httpPost.setHeader("Accept-Language", header.get("Accept-Language"));
			if(header.get("Host")!=null) httpPost.setHeader("Host", header.get("Host"));
			if(header.get("User-Agent")!=null) httpPost.setHeader("User-Agent", header.get("User-Agent"));
			if(header.get("x-requested-with")!=null) httpPost.setHeader("x-requested-with", header.get("x-requested-with"));
			if(header.get("Encoding")!=null) encoding =header.get("Encoding");
			if(header.get("Content-Type")!=null) contentType =header.get("Content-Type");
		}
		// 装填参数
		if (contentType.equalsIgnoreCase("text/html")) {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			if (params != null) {
				for (Entry<String, String> entry : params.entrySet()) {
					nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, encoding));
		}
		// JOSN格式参数
		if (contentType.equalsIgnoreCase("application/json")) {
			StringEntity myEntity = new StringEntity(JSON.toJSONString(params.get("data")),
					ContentType.create("application/json", "UTF-8"));
			httpPost.setEntity(myEntity);
		}
		CloseableHttpResponse response = client.execute(httpPost, localContext);
		// 如果需要输出cookie
		if (outCookies != null) {
			List<Cookie> cks = cookieStore.getCookies();
			for (int i = 0; i < cks.size(); i++) {
				outCookies.put(cks.get(i).getName(), cks.get(i).getValue());
			}
		}
		HttpEntity resEntity = response.getEntity();
		if (resEntity != null) {
			body = EntityUtils.toString(resEntity, encoding);
		}
		EntityUtils.consume(resEntity);
		// 释放链接
		response.close();
		return body;
	}

	public static String getCookiesStr(Map<String, String> outCookies) {
		StringBuffer cookiesBuf = new StringBuffer();
		for (Map.Entry<String, String> c : outCookies.entrySet()) {
			cookiesBuf.append(c.getKey() + "=" + c.getValue() + ";");
		}
		return cookiesBuf.toString();
	}
	public static String get(String url) throws Exception{
		return get(url,null,null);
	}
	public static String get(String url,Map<String, String> header,Map<String, String> outCookies)
			throws Exception {
		String body = "";
		String encoding ="utf-8";
		CookieStore cookieStore = new BasicCookieStore();
		HttpClientContext localContext = HttpClientContext.create();
		localContext.setCookieStore(cookieStore);
		CloseableHttpClient client = HttpClients.createDefault();

		HttpGet httpGet = new HttpGet(url);
		if(header!=null){
			if(header.get("Accept")!=null) httpGet.setHeader("Accept", header.get("Accept"));
			if(header.get("Cookie")!=null) httpGet.setHeader("Cookie", header.get("Cookie"));
			if(header.get("Accept-Encoding")!=null) httpGet.setHeader("Accept-Encoding", header.get("Accept-Encoding"));
			if(header.get("Accept-Language")!=null) httpGet.setHeader("Accept-Language", header.get("Accept-Language"));
			if(header.get("Host")!=null) httpGet.setHeader("Host", header.get("Host"));
			if(header.get("User-Agent")!=null) httpGet.setHeader("User-Agent", header.get("User-Agent"));
			if(header.get("x-requested-with")!=null) httpGet.setHeader("x-requested-with", header.get("x-requested-with"));
			if(header.get("Encoding")!=null) encoding =header.get("Encoding");
		}
		CloseableHttpResponse response = client.execute(httpGet, localContext);
		// 如果需要输出cookie
		if (outCookies != null) {
			List<Cookie> cks = cookieStore.getCookies();
			for (int i = 0; i < cks.size(); i++) {
				outCookies.put(cks.get(i).getName(), cks.get(i).getValue());
			}
		}
		HttpEntity entity = response.getEntity();
		if (entity != null) {
			body = EntityUtils.toString(entity, encoding);
		}
		EntityUtils.consume(entity);
		response.close();
		return body;
	}

	public static void downloadFile(String url, String filePath, String fileName, String cookies, Map<String, String> outCookies) throws ClientProtocolException, IOException {
		// 生成一个httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		CookieStore cookieStore = new BasicCookieStore();
		HttpClientContext localContext = HttpClientContext.create();
		localContext.setCookieStore(cookieStore);
		HttpGet httpget = new HttpGet(url);
		if (cookies != null)
			httpget.setHeader("Cookie", cookies);
		HttpResponse response = httpclient.execute(httpget, localContext);
		// 如果需要输出cookie
		if (outCookies != null) {
			List<Cookie> cks = cookieStore.getCookies();
			for (int i = 0; i < cks.size(); i++) {
				outCookies.put(cks.get(i).getName(), cks.get(i).getValue());
			}
		}

		HttpEntity entity = response.getEntity();
		InputStream in = entity.getContent();
		File fPath = new File(filePath);
		if (!fPath.exists()) {
			fPath.mkdir();
		}
		File file = new File(filePath + fileName);
		try {
			FileOutputStream fout = new FileOutputStream(file);
			int l = -1;
			byte[] tmp = new byte[1024];
			while ((l = in.read(tmp)) != -1) {
				fout.write(tmp, 0, l);
				// 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
			}
			fout.flush();
			fout.close();
		} finally {
			// 关闭低层流。
			in.close();
		}
		httpclient.close();
	}

}
